#pragma once
#include"Novel.hpp"

#include <iostream>

struct Comment 
{
    int id;
    std::string content;
    int user_id;
    int novel_id;
    std::string comment_type;
    NovelStatus status;
    std::string novel_type;

    Comment(){}
};

class CommentMapper {
private:
    sql::mysql::MySQL_Driver* driver;
    std::unique_ptr<sql::Connection> con;
    
    // 状态枚举到字符串转换
    std::string statusToString(NovelStatus status) {
        switch(status) {
            case NovelStatus::ONGOING: return "ongoing";
            case NovelStatus::COMPLETED: return "completed";
            case NovelStatus::DROPPED: return "dropped";
            default: return "ongoing";
        }
    }
    
    // 字符串到状态枚举转换
    NovelStatus stringToStatus(const std::string& status) {
        if (status == "ongoing") return NovelStatus::ONGOING;
        if (status == "completed") return NovelStatus::COMPLETED;
        if (status == "dropped") return NovelStatus::DROPPED;
        return NovelStatus::ONGOING;
    }

public:
    // 构造函数 - 初始化数据库连接
    CommentMapper(const std::string& host, const std::string& user, 
                 const std::string& password, const std::string& database) 
    {
        driver = sql::mysql::get_mysql_driver_instance();
        con.reset(driver->connect(host, user, password));
        con->setSchema(database);
    }
    
    // 1. 新增评论
    int insert(const Comment& comment) {
        try {
            std::unique_ptr<sql::PreparedStatement> pstmt(
                con->prepareStatement(
                    "INSERT INTO comment (content, user_id, novel_id, comment_type, status, novel_type) "
                    "VALUES (?, ?, ?, ?, ?, ?)"
                )
            );
            
            pstmt->setString(1, comment.content);
            pstmt->setInt(2, comment.user_id);
            pstmt->setInt(3, comment.novel_id);
            pstmt->setString(4, comment.comment_type);
            pstmt->setString(5, statusToString(comment.status));
            pstmt->setString(6, comment.novel_type);
            
            pstmt->executeUpdate();
            
            // 获取自增ID
            std::unique_ptr<sql::Statement> stmt(con->createStatement());
            std::unique_ptr<sql::ResultSet> res(stmt->executeQuery("SELECT LAST_INSERT_ID()"));
            
            if (res->next()) {
                return res->getInt(1);
            }
            return -1;
        } catch(sql::SQLException &e) {
            // 实际项目中应使用日志系统
            throw std::runtime_error("Insert failed: " + std::string(e.what()));
        }
    }
    
    // 2. 通过ID获取评论
    std::unique_ptr<Comment> getById(int id) {
        try {
            std::unique_ptr<sql::PreparedStatement> pstmt(
                con->prepareStatement(
                    "SELECT id, content, user_id, novel_id, comment_type, status, novel_type "
                    "FROM comment WHERE id = ?"
                )
            );
            
            pstmt->setInt(1, id);
            std::unique_ptr<sql::ResultSet> res(pstmt->executeQuery());
            
            if (res->next()) {
                auto comment = std::make_unique<Comment>();
                comment->id = res->getInt("id");
                comment->content = res->getString("content");
                comment->user_id = res->getInt("user_id");
                comment->novel_id = res->getInt("novel_id");
                comment->comment_type = res->getString("comment_type");
                comment->status = stringToStatus(res->getString("status"));
                comment->novel_type = res->getString("novel_type");
                return comment;
            }
            return nullptr;
        } catch(sql::SQLException &e) {
            throw std::runtime_error("Get by ID failed: " + std::string(e.what()));
        }
    }
    
    // 3. 更新评论内容
    bool update(const Comment& comment) {
        try {
            std::unique_ptr<sql::PreparedStatement> pstmt(
                con->prepareStatement(
                    "UPDATE comment SET "
                    "content = ?, user_id = ?, novel_id = ?, "
                    "comment_type = ?, status = ?, novel_type = ? "
                    "WHERE id = ?"
                )
            );
            
            pstmt->setString(1, comment.content);
            pstmt->setInt(2, comment.user_id);
            pstmt->setInt(3, comment.novel_id);
            pstmt->setString(4, comment.comment_type);
            pstmt->setString(5, statusToString(comment.status));
            pstmt->setString(6, comment.novel_type);
            pstmt->setInt(7, comment.id);
            
            return pstmt->executeUpdate() > 0;
        } catch(sql::SQLException &e) {
            throw std::runtime_error("Update failed: " + std::string(e.what()));
        }
    }
    
    // 4. 删除评论
    bool remove(int id) {
        try {
            std::unique_ptr<sql::PreparedStatement> pstmt(
                con->prepareStatement(
                    "DELETE FROM comment WHERE id = ?"
                )
            );
            
            pstmt->setInt(1, id);
            return pstmt->executeUpdate() > 0;
        } catch(sql::SQLException &e) {
            throw std::runtime_error("Delete failed: " + std::string(e.what()));
        }
    }
    
    // 5. 通过用户ID获取评论列表
    std::vector<Comment> getByUserId(int userId) {
        std::vector<Comment> comments;
        
        try {
            std::unique_ptr<sql::PreparedStatement> pstmt(
                con->prepareStatement(
                    "SELECT id, content, user_id, novel_id, comment_type, status, novel_type "
                    "FROM comment WHERE user_id = ?"
                )
            );
            
            pstmt->setInt(1, userId);
            std::unique_ptr<sql::ResultSet> res(pstmt->executeQuery());
            
            while (res->next()) {
                Comment comment;
                comment.id = res->getInt("id");
                comment.content = res->getString("content");
                comment.user_id = res->getInt("user_id");
                comment.novel_id = res->getInt("novel_id");
                comment.comment_type = res->getString("comment_type");
                comment.status = stringToStatus(res->getString("status"));
                comment.novel_type = res->getString("novel_type");
                
                comments.push_back(comment);
            }
        } catch(sql::SQLException &e) {
            throw std::runtime_error("Get by user ID failed: " + std::string(e.what()));
        }
        
        return comments;
    }
    
    // 6. 通过小说ID获取评论列表
    std::vector<Comment> getByNovelId(int novelId) {
        std::vector<Comment> comments;
        
        try {
            std::unique_ptr<sql::PreparedStatement> pstmt(
                con->prepareStatement(
                    "SELECT id, content, user_id, novel_id, comment_type, status, novel_type "
                    "FROM comment WHERE novel_id = ?"
                )
            );
            
            pstmt->setInt(1, novelId);
            std::unique_ptr<sql::ResultSet> res(pstmt->executeQuery());
            
            while (res->next()) {
                Comment comment;
                comment.id = res->getInt("id");
                comment.content = res->getString("content");
                comment.user_id = res->getInt("user_id");
                comment.novel_id = res->getInt("novel_id");
                comment.comment_type = res->getString("comment_type");
                comment.status = stringToStatus(res->getString("status"));
                comment.novel_type = res->getString("novel_type");
                
                comments.push_back(comment);
            }
        } catch(sql::SQLException &e) {
            throw std::runtime_error("Get by novel ID failed: " + std::string(e.what()));
        }
        
        return comments;
    }
};

